package com.le.sarrs.util;

import com.le.sarrs.cms.ScheduledCheckMap;
import org.apache.log4j.Logger;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class IP4Country {
    private static final Logger log = Logger.getLogger(IP4Country.class);
    private static final String DEFAULT_COUNTRY_CODE = "";
    private static final String FILE_PATH = "/Users/hexi/work/search_java/isarrsagent/target/isarrs/WEB-INF/classes/ips.csv";
    private static Map<String, LinkedHashMap<String, String>> map = Collections.synchronizedMap(new LinkedHashMap<String, LinkedHashMap<String, String>>());
    private volatile static ScheduledCheckMap schechedCheck;

    private static ScheduledCheckMap rollingRead() {
        if (null == schechedCheck) {
            schechedCheck = new ScheduledCheckMap(24, TimeUnit.HOURS) {
                @Override
                protected Map<String, LinkedHashMap<String, String>> query() {
                    map = readIPcvs();
                    return map;
                }
            };
        }
        return schechedCheck;
    }

    static {
        map = readIPcvs();
        rollingRead().getMap();
    }

    public static String getCountry(String ip) {
        if (StringUtil.isBlank(ip))
            return DEFAULT_COUNTRY_CODE;
        String result = DEFAULT_COUNTRY_CODE;
        try {
            String ipA = ip.split("\\.")[0];
            if (map.containsKey(ipA)) {
                LinkedHashMap<String, String> mm = map.get(ipA);
                for (String ipSection : mm.keySet()) {
                    if (ipExistsInRange(ip, ipSection)) {
                        result = mm.get(ipSection);
                        break;
                    }
                }
            }
        } catch (Exception ignored) {
        }
        return result;
    }

    private static Map<String, LinkedHashMap<String, String>> readIPcvs() {
        Map<String, LinkedHashMap<String, String>> result = new LinkedHashMap<>();
        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(FILE_PATH));// 换成你的文件名
            String line;
            while ((line = reader.readLine()) != null) {

                String item[] = line.split(",");// CSV格式文件为逗号分隔符文件，这里根据逗号切分
                String outerKey = item[0].split("\\.")[0];
                LinkedHashMap<String, String> foo = result.get(outerKey);
                String innerKeyA = item[1].split("\\.")[0];
                String innerKey = item[0] + "-" + item[1];
                String innerValue = item[2]; //+ "_" + item[3] + "_" + item[4] + "_" + item[5]
                int slice;
                //切割
                if ((slice = Integer.parseInt(innerKeyA) - Integer.parseInt(outerKey)) > 0) {
                    slice++;
                    int autoKey = Integer.parseInt(outerKey);
                    for (; slice > 0; ) {
                        LinkedHashMap<String, String> bar = result.get(String.valueOf(autoKey));
                        if (bar == null || bar.size() == 0) {
                            LinkedHashMap<String, String> innerMap = new LinkedHashMap<>();
                            innerMap.put(innerKey, innerValue);
                            result.put(String.valueOf(autoKey++), innerMap);
                        } else {
                            bar.put(innerKey, innerValue);
                        }
                        slice--;
                    }
                }
                if (innerValue.startsWith("0")) {
                    innerValue = DEFAULT_COUNTRY_CODE;
                }
                if (foo == null || foo.size() == 0) {
                    LinkedHashMap<String, String> innerMap = new LinkedHashMap<>();
                    innerMap.put(innerKey, innerValue);
                    result.put(outerKey, innerMap);
                } else {
                    foo.put(innerKey, innerValue);
                }
            }
        } catch (Exception e) {
            log.info("ip file parse error.", e);
        } finally {
            if (null != reader) {
                try {
                    reader.close();
                } catch (IOException ignored) {
                }
            }
        }
        return result;
    }

    /**
     * 验证IP是否属于某个IP段 ipSection IP段（以'-'分隔） ip 所验证的IP号码
     */
    private static boolean ipExistsInRange(String ip, String ipSection) {
        ipSection = ipSection.trim();
        ip = ip.trim();
        int idx = ipSection.indexOf('-');
        String beginIP = ipSection.substring(0, idx);
        String endIP = ipSection.substring(idx + 1);
        return getIp2long(beginIP) <= getIp2long(ip) && getIp2long(ip) <= getIp2long(endIP);
    }

    private static long getIp2long(String ip) {
        ip = ip.trim();
        String[] ips = ip.split("\\.");
        long ip2long = 0L;
        for (int i = 0; i < 4; ++i) {
            ip2long = ip2long << 8 | Integer.parseInt(ips[i]);
        }

        return ip2long;
    }

    public static long getIp2long2(String ip) {
        ip = ip.trim();
        String[] ips = ip.split("\\.");
        long ip1 = Integer.parseInt(ips[0]);
        long ip2 = Integer.parseInt(ips[1]);
        long ip3 = Integer.parseInt(ips[2]);
        long ip4 = Integer.parseInt(ips[3]);
        return ip1 * 256 * 256 * 256 + ip2 * 256 * 256 + ip3 * 256 + ip4;

    }
}
